// 对aixos 二次封装

// 引入axios
import axios from "axios";
// 格式化数据的第三方库
import qs from "qs";
// 网页请求进度条插件 引入
import nprogress from 'nprogress'
import "nprogress/nprogress.css"



/**
 * 环境的配置，区分生产环境和开发环境
 */
/*switch (process.env.NODE_ENV) {
    case "production":
        // 生产环境，部署到的服务器
        // baseURL配置基地址，配置之后就不需要在每个接口填写完整路径
        axios.defaults.baseURL = "http://生产真实地址";
        break;
    case "test":
        axios.defaults.baseURL = "http://测试环境";
        break;
    default:
        axios.defaults.baseURL = "http://默认环境";
        break;
}*/

/**
 * 设置超时时间，单位毫秒
 */
axios.defaults.timeout = 50000;

/**
 * 设置是否允许跨域和是否允许携带凭证，如果该设置为false，请求时不允许携带凭证
 */
axios.defaults.withCredentials = true;

/**
 * 设置请求头
 *   - 设置请求传递数据的格式，通常需要包含 `x-www-form-urlencoded` 格式，该格式的数据通常为 `xxx=xxx&yyy=yyy`，这是为了post请求与get请求的格式相同
 */
axios.defaults.headers["Content-Type"] = "application/x-www-form-urlencoded";
// 针对post请求设置数据格式，该方法transformRequest仅针对post请求有效
// 使用qs库将传入的data数据转换为 `x-www-form-urlencoded` 格式
// 当然，这需要看服务器使用什么数据格式，如果服务器使用json，那么不需要这样设置
axios.defaults.transformRequest = data => qs.stringify(data);

/**
 * 设置请求拦截器。它的执行逻辑：
 *   客户端的请求 -> 请求拦截器 -> 服务器
 * 这样可以对请求操作进行一系列的处理，再发送给服务器，比如，添加TOKEN
 */
axios.interceptors.request.use(
    config => {
        // 网页请求进度条
        nprogress.start();
        // 携带token，从本地读取到token，然后添加到请求头
        const token = localStorage.getItem("token");
        token && (config.headers.Authorization = token);
        return config;
    },
    error => {
        return Promise.reject(error);
    }
);

/**
 * 自定义响应成功的HTTP状态码
 * 通常情况下不需要，因为开发的程序一般不会出现3开头的状态码
 * 如果需要，可以打开注释
 */
// axios.defaults.validateStatus = status => {
//   return /^(2|3)\d{2}$/.test(status);
// };

/**
 * 响应拦截器。它的知性逻辑：
 *   服务器返回信息 -> 相应拦截器 -> 客户端获取到信息
 * 这样可以首先对响应的信息做一些预处理，从而使得客户端的代码更加整洁
 */
axios.interceptors.response.use(
    response => {
        nprogress.done();

        // 成功后返回response的主体，其他数据一般并不需要，这样在使用中只需要关注数据主体就可以
        return response.data;
    },
    error => {
        let { response } = error; // 等效于error.response
        if (response) {
            // 服务器返回了结果
            // 这里能够读出服务器返回的错误HTTP状态码，根据不同状态码进行不同处理
            // 这个根据业务需求操作即可
            switch (response.status) {
                case 401:
                    // 权限不够，一般是未登录
                    // sessionStorage.user = ''
                    //     sessionStorage.token = ''
                    //     window.location.href = '/';//返回登录页
                    break;
                case 403:
                    // 服务器已经接受，但是拒绝访问，通常是登录过期
                    // ...
                    localStorage.removeItem("token");
                    break;
                case 404:
                    // 找不到资源
                    // ...
                    break;
            }
        } else {
            // 服务器根本就没有返回任何东西
            // 这里一般只有两种情况，服务器崩溃，客户端没有网。
            // 通常在这里做断网处理
            if (!window.navigator.onLine) {
                // 处理断网
                // ...
                return;
            }
            // 什么都不是，返回一个错误
            return Promise.reject(error);
        }
    }
);

// 都写好，最后将axios导出
export default axios;
